#include "stdafx.h"
#include "dev_serv.h"

void GetRTCFull(CRuntimeClass* rtc, CString& Str)
{
    if (rtc)
    {
        Str.Format("%s%s%s(%d/%d)", Str, "<-", rtc->m_lpszClassName, rtc->m_nObjectSize, rtc->m_nObjectSize - (rtc->m_pfnGetBaseClass() ? rtc->m_pfnGetBaseClass()->m_nObjectSize : 0));
        GetRTCFull(rtc->m_pfnGetBaseClass(), Str);
    }
}

void MessageFullRTC(CObject* obj, CString Indent)
{
        if (obj)
        {
                CString Str;
                GetRTCFull(obj->GetRuntimeClass(), Str);
                DoMsgLine("%s%s", mmNone, Indent, Str);
        }
}

void TraceProfile(CProfile7* pProf, CString Indent)
{
        if (!pProf)
        {
                CApp7* pApp7 = (CApp7*)AfxGetApp();
                pProf = pApp7->GetProps();
        }

        DoMsgLine("%s%s # %s # %d", mmNone, Indent, pProf->m_strKey, pProf->m_strPath, pProf->GetEntryCount());
        CString str;
        for (int i=0; i<pProf->GetEntryCount(); i++)
        {
                ((CProfile7_*)pProf)->PropToString(i, str);
                const CProfileEntry7* pPE = pProf->GetEntryAt(i);
                DoMsgLine("%s%s[%d] %d %s: %s", mmNone," ",Indent, i, pPE->type, pPE->EntryName, str);
        }

        POSITION pos = pProf->GetFirstProfile();
        while(pos)
                TraceProfile(pProf->GetNextProfile(pos), Indent+"  ");
}

void TraceWindows(CWnd* pWnd, CString Indent)
{
        CString Str;
        GetRTCFull(pWnd->GetRuntimeClass(), Str);
        DoMsgLine("%s%s", mmNone, Indent, Str);
		if (pWnd->IsKindOf(RUNTIME_CLASS(CView)))
		{
			CView* pView = (CView*)pWnd;
			Str.Empty();
			GetRTCFull(pView->GetParentFrame()->GetRuntimeClass(), Str);
	        DoMsgLine("%s(Frame:%s)", mmNone, Indent, Str);
			Str.Empty();
			GetRTCFull(pView->GetDocument()->GetRuntimeClass(), Str);
	        DoMsgLine("%s(Document:%s)", mmNone, Indent, Str);
		};
        for (pWnd = pWnd->GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetWindow(GW_HWNDNEXT))
                TraceWindows(pWnd, Indent+"  ");
}

void TraceMenu(CMenu* Menu, CString Indent)
{
        if (Menu)
        {
                CString str;
                MENUITEMINFO mii;
                for (int i=0; i<Menu->GetMenuItemCount(); i++)
                {
                        Menu->GetMenuString(i, str, MF_BYPOSITION);
                        DWORD id = Menu->GetMenuItemID(i);
                        Menu->GetMenuItemInfo(i, &mii, MF_BYPOSITION);
                        DoMsgLine("%s%d %08X %s", mmNone, Indent, id, mii.fState, str);
                        TraceMenu(Menu->GetSubMenu(i), Indent+"  ");
                }
        }
}

void TraceBLContext(CBLContext* pBLC, CString Indent)
{
        MessageFullRTC(pBLC, Indent);
        DoMsgLine("%sNProps:%d NMethods:%d", mmNone,Indent, pBLC->GetNProps(), pBLC->GetNMethods());
        int i;
        for (i = 0; i < pBLC->GetNProps(); i++)
        {
                DoMsgLine("%s%02d %s%s %s/%s", mmNone,
                        Indent+"  ",
                        i,
                        pBLC->IsPropReadable(i)?"r":"",
                        pBLC->IsPropWritable(i)?"w":"",
                        pBLC->GetPropName(i,0),
                        pBLC->GetPropName(i,1)
                        );
        }
        for (i = 0; i < pBLC->GetNMethods(); i++)
        {
                DoMsgLine("%s%02d %s %s/%s(%d)", mmNone,
                        Indent+"  ",
                        i,
                        pBLC->HasRetVal(i)?"=":" ",
                        pBLC->GetMethodName(i,0),
                        pBLC->GetMethodName(i,1),
                        pBLC->GetNParams(i)
                        );
        }
}

void TraceGC(CBLContext* pBLC, CString Indent, BOOL Detail)
{
        if (strcmp("CGroupContext", pBLC->GetRuntimeClass()->m_lpszClassName)&&
                strcmp("CAutoGroupContext", pBLC->GetRuntimeClass()->m_lpszClassName))
                return;
        CGroupContext* pGC = (CGroupContext*)pBLC;

        MessageFullRTC(pBLC, Indent);
        DoMsgLine("%sNMethods:%d NProps:%d", mmNone,Indent, pGC->GetNMethods(), pGC->GetNProps());
        for(int i = 0; Detail && i < pGC->GetSize(); i++)
        {
                TraceBLContext(pGC->GetContext(i), Indent+"  ");
        }

}